const Party = require("./party.js");
const db_handler = require('../db_handler.js');
const { logger } = require("../logger.js");

class Player {
    constructor(data) {
        this.name = data.name;
        this.characterName = data.character_name;
        this.characterIndex = data.character_index;
        this.level = data.level;
        this.faceName = data.face_name;
        this.faceIndex = data.face_index;
        this.classId = data.class_id;
        this.mapId = data.map_id;
        this.x = data.map_x;
        this.y = data.map_y;
        this.title = data.title;
        this.uid = data.uid;
        this.partyPend = null;
        this.party = null;
        this.guild = null;
        this._socket = data.socket;
        this._lastRefreshTime = 0;
    }

    logon() {
        const { uid, name } = this;
        //获取队伍信息
        const party = parties.get(uid);
        const data = { "party": party?.makeData(), "actor": this.makeBaseData() };
        //设置对象
        this.setParty(party);
        //设置全局变量
        players.set(uid, this);
        //向前端发送玩家角色基础数据
        this._socket.emit("actor base info", data);
        //日志
        logger.info(`玩家 [${uid}]${name} 进入游戏...`);
    }

    offline() {
        this.leaveMap();
        const { mapId, x, y, uid, name } = this;
        //将角色位置保存至数据库
        const data = { mapId, x, y };
        db_handler.updatePosition(uid, data);
        //清理对象
        this._socket.removeAllListeners();
        this._socket = null;
        //清理全局变量
        players.delete(uid);
        //日志
        logger.info(`玩家 [${uid}]${name} 离开了游戏,位于地图 ${mapId}`);
    }

    transfer(data, room) {
        this.leaveMap();
        this.joinMap(data, room);
        //日志
        const text = room === 0 ? "" : `由地图 ${room} `;
        logger.info(`玩家 [${this.uid}]${this.name} ${text}进入了地图 ${this.mapId} ...`);

    }

    leaveMap() {
        if (!this.mapRoom) return;
        const { mapId, mapRoom, uid } = this;
        this._socket.leave(mapRoom);
        this._socket.to(mapRoom).emit("leave map", { "uid": uid, "mapId": mapId });
    }

    joinMap(data, room) {
        const { newMapId, x, y } = data;
        this.mapId = newMapId;
        this.x = x;
        this.y = y;
        this.mapRoom = room;
        this._socket.join(room);
        this._socket.to(room).emit("enter map", this.makeBaseData());
    }

    move(x, y) {
        this.x = x;
        this.y = y;
        const { mapRoom, uid, mapId } = this;
        const data = { mapId, x, y, uid };
        this._socket.to(mapRoom).emit("move", data);
        this._lastRefreshTime = Date.now();
    }

    changeMapState(state) {
        const { mapRoom, uid } = this;
        const data = { state, uid };
        this.mapState = state;
        this._socket.to(mapRoom).emit("player map state", data);
    }

    makeBaseData() {
        const { name, level, characterName, characterIndex, faceName, faceIndex, classId, x, y, title, uid, mapId } = this;
        const data = { name, level, characterName, characterIndex, faceName, faceIndex, classId, x, y, title, uid, mapId };
        return data;
    }

    getParty() {
        if (!this.party) this.createParty();
        return this.party;
    }

    createParty() {
        const party = new Party();
        party.setLeader(this);
        this.party = party;
        const room = party.getRoom();
        this._socket.join(room);
        //通知创建成功
        this._socket.emit("tip pop", "队伍创建成功！");
    }

    partyInvite(party) {
        const data = party.makeData();
        this._partyPend = party;
        this._socket.emit("party invite", data);
    }

    partyAgree() {
        if (this._partyPend) {
            this.partyJoin(this);
        }
    }

    partyRefuse() {
        // const leader = this._partyPend.
        if (this._partyPend) {
            this._partyPend = null;
        }
    }

    partyJoin() {
        const party = this._partyPend;
        const room = party.getRoom();
        party.join(this);
        this.party = party;
        this._partyPend = null;
        this._socket.join(room);
    }

    leaveParty() {
        const { party, uid, name } = this;
        //判断队伍是否存在
        if (!party) return;
        const room = party.getRoom();
        //判断是否是队长，如果时队长则解散队伍
        if (party.leader === uid) {
            this._socket.to(room).emit("party dissolve");
            for (const member of party.data.values()) {
                //将队伍所有成员清除队伍信息
                member.clearPartyInfo();
            }
            party.dissolve();
            return;
        }
        //不是队长，则正常离队
        this.clearPartyInfo();
        //清除自身的全局队伍信息
        const partyData = party.makeData();
        const code = 132;
        const obj = [name];
        const data = { partyData, code, obj };
        this._socket.to(partyRoom).emit("updata party", data);
    }

    clearPartyInfo() {
        const { party, uid } = this;
        if (!party) return;
        const room = party.getRoom();
        parties.delete(uid);
        this._socket.leave(room);
        this.party = null;
    }

    setParty(party) {
        this.party = party;
    }
}

module.exports = Player;